﻿using System;
using System.IO;
using System.Web;
using PmfWeb.Core.Utility;

namespace PmfWeb.Core.HttpHandlers
{
    /// <summary>
    /// 文件下载处理器,需要在web.config上添加一下项
    /// <system.web>
        //  <httpHandlers>
        //    <add verb="*" path="download.aspx" type="DownloadHandler" />
        //  </httpHandlers>
        //</system.web>
    /// </summary>

    public class DownloadHandler : IHttpHandler
    {
        ///<summary>
        /// 处理请求
        ///</summary>
        public void ProcessRequest(HttpContext context)
        {
            HttpResponse response = context.Response;
            System.IO.Stream iStream = null;
            byte[] buffer = new byte[10240];
            int length;
            long dataToRead;
            try
            {
                string filename = DESncrypt.DecryptToBase64(context.Request["fn"]); //通过解密得到文件名

                string filepath = HttpContext.Current.Server.MapPath("~/") + "files/" + filename; //待下载的文件路径

                iStream = new System.IO.FileStream(filepath, System.IO.FileMode.Open,
                                                   System.IO.FileAccess.Read, System.IO.FileShare.Read);
                response.Clear();

                dataToRead = iStream.Length;

                long p = 0;
                //断点续传
                if (context.Request.Headers["Range"] != null)
                {
                    context.Response.StatusCode = 206;
                    p = long.Parse(context.Request.Headers["Range"].Replace("bytes=", "").Replace("-", ""));
                }
                if (p != 0)
                {
                    context.Response.AddHeader("Content-Range",
                                               "bytes " + p.ToString() + "-" + ((long) (dataToRead - 1)).ToString() +
                                               "/" + dataToRead.ToString());
                }
                context.Response.AddHeader("Content-Length", ((long) (dataToRead - p)).ToString());
                context.Response.ContentType = "application/octet-stream";
                context.Response.AddHeader("Content-Disposition",
                                           "attachment; filename=" +
                                           System.Web.HttpUtility.UrlEncode(
                                               System.Text.Encoding.GetEncoding(65001).GetBytes(
                                                   Path.GetFileName(filename))));

                iStream.Position = p;
                dataToRead = dataToRead - p;

                while (dataToRead > 0)
                {
                    if (context.Response.IsClientConnected)
                    {
                        length = iStream.Read(buffer, 0, 10240);

                        context.Response.OutputStream.Write(buffer, 0, length);
                        context.Response.Flush();

                        buffer = new Byte[10240];
                        dataToRead = dataToRead - length;
                    }
                    else
                    {
                        dataToRead = -1;
                    }
                }
            }
            catch (Exception ex)
            {
                context.Response.Write("Error : " + ex.Message);
            }
            finally
            {
                if (iStream != null)
                {
                    iStream.Close();
                }
                context.Response.End();
            }
        }

        /// <summary>
        /// 是否缓存
        /// </summary>
        public bool IsReusable
        {
            get { return true; }
        }
    }
}
